home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 21
/
Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso
/
Aminet
/
comm
/
bbs
/
cit_src_7H21.lha
/
syszm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-27
|
16KB
|
662 lines
/*
* * syszm.c * * External protocol handlers.
*/
/*
* * history * * 89Aug14 HAW Rewritten for versatility. * 88Nov13 HAW
* Created.
*/
#define SYSTEM_DEPENDENT
#include "ctdl.h"
#include "dos.h"
int Jsystem(char *);
long Do_Zmodem(char *files, int direction);
/** returns TRUE if error **/
/**
Contents
AddExternProtocolOptions() to system menus
AddNames() Allows building strings of names
AddOurOpts() add options to a menu list.
DoesNumerous() BATCH checking function.
EatExtMessage() Send a bundle of messages
EatProtocol() Eats a protocol definition line.
ExternalProtocol() Handles all external protocols
FindProtocolCode() finds a protocol value for id purposes
FindProtoName() returns the name of the ext protocol.
FindProtocol() work function for finding things.
InitProtocols() initializes external protocols
**/
char MakeCmdLine(char *, char *, char *miscdata, int len);
void AddName(DirEntry *);
int ExternalProtocol(int, char, char *, char *, char);
typedef struct
{
char Selector,
*Name,
Down,
*CmdLine,
*Display,
Many;
int ProtVal;
}
PROTOCOL;
char GetSizes = FALSE;
int ExCount = 4;
void *EatProtocol(char *line);
void *FindProtocol(PROTOCOL *, int *);
void InitProtocols(void);
static SListBase ExtProtocols =
{
NULL, FindProtocol, NULL, NULL, EatProtocol
};
static char FindCode = FALSE;
extern CONFIG cfg;
extern MessageBuffer msgBuf;
extern aRoom roomBuf;
extern char loggedIn;
extern int SystemPort;
extern char onConsole; /*
* Where we get stuff from
*/
extern logBuffer logBuf;
char AddStringToMCL(char *target, char *source, int len);
void EnglishWork(char *target, char Ups);
char cmdline[125]; /* we have a limit */
/*
* * InitProtocols() * * This function initializes external protocols.
*/
void
InitProtocols()
{
SYS_FILE fn;
makeSysName(fn, "ctdlprot.sys", &cfg.roomArea);
MakeList(&ExtProtocols, fn, NULL);
}
/**
EatProtocol()
This function eats a protocol line.
Format:
[selector] [1/M] [name] [u/d] [command line]
[selector] [I] [name] [u/d] [Internal Zmodem]
**/
void *
EatProtocol(char *line)
{
PROTOCOL *temp;
char *c,
*err;
if (cfg.BoolFlags.debug)
splitF(NULL, "External:%s\n", line);
err = line;
NormStr(line);
if (strLen(line) == 0)
return NULL;
temp = GetDynamic(sizeof *temp);
temp->Selector = line[0];
line += 2;
temp->Many = toUpper(line[0]);
/**
Could be "1" or "M"
**/
switch (temp->Many)
{
case '1': /*
* Single file, external protocol handler
*/
case 'M': /*
* Multiple files, external protocol handler
*/
case 'I': /*
* Internal Zmodem
*/
break;
default:
splitF(NULL, "Invalid Protocol in CTDLPROT.SYS\n%s\n", err);
}
line += 2;
if ((c = strchr(line, ' ')) != NULL)
*c = 0;
temp->Name = strdup(line);
line = lbyte(line) + 1;
temp->Down = (toUpper(line[0]) == 'D') ? TRUE : FALSE;
line += 2;
temp->CmdLine = strdup(line);
temp->ProtVal = ExCount++;
sPrintf(cmdline, "%s%c\b%s", NTERM, temp->Selector, temp->Name);
temp->Display = strdup(cmdline);
return temp;
}
/**
ExternalProtocol()
This function handles external protocols. It
also checks for external message uploads/downloads.
**/
int
ExternalProtocol(int protocol, char upload, char *mask, char *phrase,
char Move)
{
PROTOCOL *Prot;
int toReturn;
extern long byteRate;
extern int SystemPort;
SpecialMessage("Status:External Protocol");
if (cfg.BoolFlags.debug)
{
splitF(NULL, "ExternalProtocol(%d,%s,%s,%s,%s)\n", protocol,
(upload ? "TRUE" : "FALSE"), mask, phrase, (Move ? "TRUE" : "FALSE"));
};
if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
{
if (cfg.BoolFlags.debug) splitF(NULL, "SearchList failed to find Protocol\n");
return TRAN_FAILURE;
};
if (Move && !setSpace(&roomBuf))
{
if (cfg.BoolFlags.debug) splitF(NULL, "SetSpace Failed\n");
return TRAN_FAILURE;
};
if (!upload)
{
msgBuf.mbtext[0] = 0;
wildCard(AddName, mask, FALSE, phrase, TRUE);
}
else
strCpy(msgBuf.mbtext, mask);
if (Prot->Many == '1' || Prot->Many == 'M') /*
* old style
*/
{
if (cfg.BoolFlags.debug) splitF(NULL, "Making external command line\n");
if (!MakeCmdLine(cmdline, Prot->CmdLine, msgBuf.mbtext, sizeof cmdline - 1))
{
if (strchr(mask, '>') != NULL || strchr(mask, '<') != NULL)
{
if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
if (Move) homeSpace();
return TRAN_FAILURE;
}
else if (!MakeCmdLine(cmdline, Prot->CmdLine, mask, sizeof cmdline - 1))
{
if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
if (Move) homeSpace();
return TRAN_FAILURE;
}
};
};
if (!upload)
fileMessage(FL_START, mask, TRUE, protocol, 0l);
if (loggedIn)
printf("\n(%s)\n %s", logBuf.lbname, cmdline);
if (Prot->Many == '1' || Prot->Many == 'M') /* old style */
{
Jsystem(cmdline);
}
else
/**
Internal Zmodem
**/
{
if( Do_Zmodem(msgBuf.mbtext, upload) )
return TRAN_FAILURE ;
};
if (!upload)
{
GetSizes = TRUE;
ExCount = 0;
strCpy(msgBuf.mbtext, " ");
(void)wildCard(AddName, mask, Move, phrase, TRUE);
GetSizes = FALSE;
if (Move) homeSpace();
fileMessage(FL_EX_END, mask, TRUE, protocol, 0l /*
* filled in
*/ );
toReturn = TRAN_SUCCESS;
/* if( realCount > 0 )transRecDown(mask, realCount); */
}
else
{
toReturn = ((strcmp(mask, "msg") == 0) || (access(mask, 0) == 0))
? TRAN_SUCCESS : TRAN_FAILURE;
}
return toReturn;
}
UNS_16 intrates[] =
{
30, 120, 240, 480, 960, 1440, 1920, 3840, 5760
};
/*
* * MakeCmdLine() * * This function creates a command line, including
* supported substitution * parameters. This should be detailed in this
* comment but isn't.
*/
char
MakeCmdLine(char *target, char *source, char *miscdata, int len)
{
extern int thisLog; /*
* entry currently in logBuf
*/
char *c,
*temp,
NoOverflow = TRUE;
int i;
long the_bps;
for (i = 0, c = source; *c; c++)
{
if (i > len - 2)
{
NoOverflow = FALSE;
break;
}
if (*c == '%')
{
target[i] = 0;
c++;
switch (*c)
{
case 'a': /* baud rate */
if (onConsole)
sPrintf(lbyte(target), "%d", 0);
else
sPrintf(lbyte(target), "%ld",
(cfg.DepData.LockPort != -1) ?
(long)(intrates[cfg.DepData.LockPort] * 10) : byteRate * 10);
break;
case 'b': /* bps */
if( onConsole )
{
the_bps = 0;
}
else if( cfg.DepData.LockPort == -1 )
{
the_bps = byteRate;
}
else
{
the_bps = (long)(intrates[cfg.DepData.LockPort]);
};
sPrintf(lbyte(target), "%ld", the_bps);
break;
case 'c': /* port # */
sPrintf(lbyte(target), "%d", SystemPort);
break;
case 'e': /* log number of the user */
sPrintf(lbyte(target), "%d", thisLog);
break;
case 'f': /* ANSI code of the user */
sPrintf(lbyte(target), "0");
break;
case 'g': /* file mask */
NoOverflow = AddStringToMCL(target, miscdata, len);
break;
case 'h':
if (byteRate != 0)
sPrintf(lbyte(target), "COM%d", SystemPort);
else
strCat(target, "LOCAL");
break;
case 'i':
NoOverflow = AddStringToMCL(target, roomBuf.rbname, len);
break;
case 'j':
if ((temp = FindDirName(roomBuf.rbArea)) != NULL)
NoOverflow = AddStringToMCL(target, temp, len);
break;
case 'k':
sPrintf(lbyte(target), "%d", logBuf.lbwidth);
break;
case 'd':
strCat(target, logBuf.lbname);
break;
}
while (target[i])
i++;
}
else
target[i++] = *c;
}
target[i] = 0;
if (cfg.BoolFlags.debug)
splitF(NULL, "Command Line is %d long\n", strlen(target));
return NoOverflow;
}
/*
* * AddStringToMCL() * * This adds a string as needed, I guess.
*/
char
AddStringToMCL(char *target, char *source, int len)
{
if (strlen(source) + strlen(target) < len - 2)
{
strCat(target, source);
return TRUE;
}
else
{
strncpy(lbyte(target), source, len - strlen(target) - 1);
target[len - 1] = 0;
return FALSE;
}
}
static char **TheOpts,
IsUpload;
/*
* * AddExternProtocolOptions() * * This function adds external protocol
* options to system menus.
*/
void
AddExternProtocolOptions(char **Opts, char upload)
{
void AddOurOpts();
TheOpts = Opts;
IsUpload = upload;
RunList(&ExtProtocols, AddOurOpts);
}
/*
* * AddOurOpts() * * This function does the actual work of adding an option
* to a menu list.
*/
void
AddOurOpts(PROTOCOL * d)
{
if ((d->Down && IsUpload) ||
(!d->Down && !IsUpload))
return;
ExtraOption(TheOpts, d->Display);
}
/*
* * FindProtocolCode() * * This function finds a protocol value for id
* purposes.
*/
int
FindProtocolCode(int c, char upload)
{
PROTOCOL *Prot;
FindCode = TRUE;
IsUpload = upload;
if (isalpha(c))
c = toUpper(c);
Prot = SearchList(&ExtProtocols, &c);
FindCode = FALSE;
if (Prot == NULL)
return -1;
return Prot->ProtVal;
}
/*
* * FindProtoName() * * This function returns the name of the external
* protocol.
*/
char *
FindProtoName(int protocol)
{
PROTOCOL *Prot;
if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
return NULL;
return Prot->Name;
}
/*
* * FindProtocol() * * This work function helps find a protocol in a list.
*/
void *
FindProtocol(PROTOCOL * d, int *val)
{
if (FindCode)
{
if (*val == d->Selector && IsUpload != d->Down)
return d;
}
else if (*val == d->ProtVal)
return d;
return NULL;
}
/*
* * DoesNumerous() * * Does this protocol support BATCH downloads?
*/
char
DoesNumerous(int protocol)
{
PROTOCOL *Prot;
if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
return FALSE;
return (char) (Prot->Many == 'M' || Prot->Many == 'I');
}
/*
* * EatExtMessage() * * This function eat a message upload using an
* external protocol. It returns * TRAN_SUCCESS on success, TRAN_FAILURE
* otherwise.
*/
int
EatExtMessage(int protocol)
{
struct FileInfoBlock *info;
int result;
extern char TDirBuffer[];
char dir[80];
MakeTempDir();
if ((result = ExternalProtocol(protocol, TRUE, "msg", "", FALSE)) == TRAN_SUCCESS)
{
chdir(TDirBuffer);
info = (struct FileInfoBlock *) calloc(1, sizeof(struct FileInfoBlock));
if (info == NULL)
{
splitF(NULL, "Unable to get memory for info buffer(syszm)\n");
}
else
{
result = dfind(info, ALL_FILES, 0); /*
* get the filename
*/
if (result == 0)
{
if (cfg.BoolFlags.debug)
splitF(NULL, "Ingesting:", info->fib_FileName);
ingestFile(info->fib_FileName, &msgBuf);
unlink(info->fib_FileName);
}
else
splitF(NULL, "No file found!(syszm)\n");
free(info);
};
}
else
{
splitF(NULL, "Transfer failed(syszm)\n");
if (cfg.BoolFlags.debug)
{
(void) getcd(0, dir);
splitF(NULL, " Dir:%s\n Other:%s\n", dir, TDirBuffer);
};
};
homeSpace();
rmdir(TDirBuffer);
return result;
}
/*
* * AddName() * * This function is used in conjunction with wildCard to
* generate a list * of names, optionally with filesizes in parenthesis
* 4/line. This is used * to generate a command line or a report in
* FILELOG.SYS.
*/
void
AddName(DirEntry * file)
{
if (strLen(msgBuf.mbtext) > MAXTEXT - 200)
{
if (GetSizes)
strCat(msgBuf.mbtext, ".");
}
else
{
sPrintf(lbyte(msgBuf.mbtext), " %s", file->unambig);
if (GetSizes)
{
sPrintf(lbyte(msgBuf.mbtext), " (%ld)", file->FileSize);
if (++ExCount == 4)
{
strCat(msgBuf.mbtext, "\n ");
ExCount = 0;
}
}
}
}
static char *msgText,
UpsOnly;
/*
* * UpProtsEnglish() * * This generates a list of upload protocol names.
* It is used by the help * system.
*/
void
UpProtsEnglish(char *target)
{
EnglishWork(target, TRUE);
}
/*
* * DownProtsEnglish() * * This function generates a list of download
* protocol names for use by the * help system.
*/
void
DownProtsEnglish(char *target)
{
EnglishWork(target, FALSE);
}
/*
* * EnglishWork() * * This function does the real work of generating names.
*/
void List_Names(PROTOCOL *);
void
EnglishWork(char *target, char Ups)
{
char *c;
target[0] = 0;
msgText = target;
UpsOnly = Ups;
RunList(&ExtProtocols, List_Names);
if ((c = strrchr(target, ',')) == NULL)
strCpy(target, "None.");
else
strCpy(c, ".");
}
/*
* * List_Names() * * This function helps build the list of protocols
* available.
*/
void
List_Names(PROTOCOL * d)
{
char *c;
if (UpsOnly != d->Down)
{
c = lbyte(msgText);
sPrintf(c, "<%c>%s, ", d->Selector, (d->Selector == d->Name[0]) ?
d->Name + 1 : d->Name);
}
}
/*
* * ExternalTransfer() * * This function is used by the network for
* external protocol transfers.
*/
char
ExternalTransfer(int protocol, char *filename)
{
PROTOCOL *Prot;
char *name,
*fn;
if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
return FALSE;
fn = strdup(filename);
if ((name = strrchr(fn, '\\')) != NULL)
{
*name++ = 0;
chdir(fn);
}
else
{
name = fn;
}
if (!MakeCmdLine(cmdline, Prot->CmdLine, name, sizeof cmdline - 1))
{
free(fn);
return FALSE;
}
Jsystem(cmdline);
free(fn);
homeSpace();
return TRUE;
}